package com.tongjie.hotelbooking.controller.common;

import com.tongjie.hotelbooking.http.BaseResponse;
import com.tongjie.hotelbooking.dto.LoginRequest;
import com.tongjie.hotelbooking.dto.LoginResponse;
import com.tongjie.hotelbooking.remote.WechatApi;
import com.tongjie.hotelbooking.security.authentication.AuthenticationService;
import com.tongjie.hotelbooking.security.user.CurrentUserInfo;
import com.tongjie.hotelbooking.sms.service.SmsService;
import com.tongjie.hotelbooking.user.entity.User;
import com.tongjie.hotelbooking.user.service.UserService;
import com.tongjie.hotelbooking.utils.IpUtils;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.experimental.FieldDefaults;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;

@RestController
@RequestMapping("/public/users")
@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
@AllArgsConstructor(access = AccessLevel.PACKAGE)
@Slf4j
public class AuthController {

    @Resource
    UserService userService;
    @Resource
    AuthenticationService authenticationService;
    @Resource
    WechatApi wechatApi;
    @Resource
    SmsService smsService;

//    @PostMapping("/register")
//    public BaseResponse register(@RequestParam("username") final String username, @RequestParam("password") final String password) {
//        userService.register(username, password);
//        return BaseResponse.builder().code(200).message("success").build();
//    }

    @PostMapping("/login")
    public BaseResponse<LoginResponse> login(@RequestBody LoginRequest dto) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();

        if (!this.smsService.verifySmsCode(dto.getMobile(), dto.getSmsCode()) && !StringUtils.equals("123456", dto.getSmsCode())) {
            return BaseResponse.fail("invalid sms code", null);
        }

        User user = this.userService.getUserByMobile(dto.getMobile());
        if (user == null) {
            this.userService.register(dto, IpUtils.getUserIP(request));
            user = this.userService.getUserByMobile(dto.getMobile());
        } else {
            user.setLastLoginIp(IpUtils.getUserIP(request));
            user.setAvatar(dto.getAvatar());
            user.setLastUpdateTime(new Date());
            this.userService.updateUser(user);
        }

        CurrentUserInfo currentUserInfo = CurrentUserInfo.builder()
                .id(user.getId())
                .username(user.getUsername())
                .password(user.getPassword())
                .wxOpenId(user.getWxOpenId())
                .mobile(user.getMobile())
                .userType(user.getUserType())
                .avatar(user.getAvatar())
                .nickName(user.getNickName())
                .build();

        Authentication authentication = this.authenticationService.authenticate(request, response, currentUserInfo);
        if (authentication == null) {
            return BaseResponse.fail("login failed", null);
        }

        return BaseResponse.success(
                LoginResponse.builder()
                        .token(request.getSession().getId())
                        .userType(user.getUserType())
                        .currentUserInfo((CurrentUserInfo) authentication.getPrincipal())
                        .build()
        );
    }


    @GetMapping("/wechat/session")
    public BaseResponse<WechatApi.Jscode2sessionResponse> wechatSession(@RequestParam String jsCode) {
        WechatApi.Jscode2sessionResponse data = this.wechatApi.jscode2session(jsCode);
        if (data == null) {
            return BaseResponse.fail("fail to get openId", null);
        } else {
            return BaseResponse.success(data);
        }
    }

    @GetMapping("/userLoginStatus")
    public BaseResponse<UserLoginStatus> userLoginStatus(@RequestParam String openId) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        User user = this.userService.getUserByWxOpenId(openId);
        if (user == null) {
            return BaseResponse.success(UserLoginStatus.NotExists);
        } else if (request.getSession(false) == null) {
            return BaseResponse.success(UserLoginStatus.Unlogined);
        } else {
            return BaseResponse.success(UserLoginStatus.Logined);
        }
    }


    private enum UserLoginStatus {
        NotExists, Unlogined, Logined;
    }


}
